package hr.ctg.domain.action.objekt;

import hr.ctg.domain.model.Mjesto;
import hr.ctg.domain.model.Objekt;
import hr.ctg.domain.model.Otok;
import hr.ctg.domain.model.TipObjekta;
import hr.ctg.domain.model.Zupanija;
import hr.ctg.service.dao.MjestoDAO;
import hr.ctg.service.dao.ObjektDAO;
import hr.ctg.service.dao.OtokDAO;
import hr.ctg.service.dao.TipObjektaDAO;
import hr.ctg.service.dao.ZupanijaDAO;
import hr.web.jsf.model.PagedListDataModel;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.component.UISelectOne;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;

import org.jboss.seam.Component;
import org.jboss.seam.annotations.Factory;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.web.RequestParameter;

//@Scope(ScopeType.CONVERSATION)
@Name("objektSearch")
public class ObjektSearchAction implements Serializable {
	private static final long serialVersionUID = 1655742302;

	private static final int PAGE_SIZE = 20;

	@In
	MjestoDAO mjestoDAO;
	@In
	ZupanijaDAO zupanijaDAO;
	@In
	TipObjektaDAO tipObjektaDAO;
	@In
	OtokDAO otokDAO;
	@In(required = false)
	private SearchParameters searchParameters;

	@RequestParameter
	private Integer page;
	@RequestParameter
	private Integer idTipaObjekta;
	@RequestParameter
	private Integer idMjesta;
	@RequestParameter
	private Integer idOtoka;
	@RequestParameter
	private Integer idZupanije;

	private List<Zupanija> zupanije;
	private List<Otok> otoci;
	private List<Mjesto> mjesta;
	private Mjesto mjesto;

	private UISelectOne selectZupanija;
	private UISelectOne selectOtok;
	private UISelectOne selectMjesto;
	private UISelectOne selectPosta;
	private UISelectOne selectTipObjekta;

	public List<Mjesto> getMjesta() {
		if (getSelectOtok().getValue() != null) {
			mjesta = mjestoDAO.findByIdOtokaObjekti(((Otok) getSelectOtok()
					.getValue()).getIdOtoka());
		} else if (getSelectZupanija().getValue() != null) {
			mjesta = mjestoDAO
					.findByIdZupanijeObjekti(((Zupanija) getSelectZupanija()
							.getValue()).getIdZupanje());
		} else {
			mjesta = mjestoDAO.findByObjekti();
		}

		return mjesta;
	}

	public List<Mjesto> getMjesta(final Object suggest) {
		final String pref = (String) suggest;
		if (searchParameters.getNazivOtoka() != null
				&& !searchParameters.getNazivOtoka().equals("")) {
			mjesta = mjestoDAO.findByNazivOtokaLikeNaziv(searchParameters
					.getNazivOtoka(), pref + "%");
		} else if (getSelectZupanija().getValue() != null) {
			mjesta = mjestoDAO.findByIdZupanijeLikeNaziv(Integer
					.valueOf(Integer.parseInt((String) getSelectZupanija()
							.getValue())), pref + "%");
		} else {
			mjesta = mjestoDAO.findByObjektiLikeNaziv(pref + "%");
		}

		return mjesta;
	}

	public List<Otok> getOtoci() {
		if (getSelectZupanija().getValue() != null) {
			otoci = otokDAO
					.findByIdZupanijeObjekti(((Zupanija) getSelectZupanija()
							.getValue()).getIdZupanje());
		} else {
			otoci = otokDAO.findByObjekti();
		}

		return otoci;
	}

	public void orderBy(final String order, final boolean asc) {
		searchParameters.setOrder(order);
		searchParameters.setAsc(asc);
		// return "/guides/objekti/list.xhtml";
	}

	public List<Zupanija> getZupanije() {
		if (zupanije == null) {
			zupanije = zupanijaDAO.findByObjekti();
		}

		return zupanije;
	}

	public void onOtokSelected(final ValueChangeEvent event) {
		getSelectMjesto().setValue(null);

		// FacesContext.getCurrentInstance().renderResponse();
	}

	public void onZupanijaSelected(final ValueChangeEvent event) {
		if (event.getNewValue() != null) {
			getSelectOtok().setValue(null);
			// selectPosta.setValue(null);
			getSelectMjesto().setValue(null);
		}
		// nije potrebno, bypasUpdate on a:support == true
		// FacesContext.getCurrentInstance().renderResponse();
	}

	@Factory("tipoviObjekata")
	public List<TipObjekta> getTipoviObjekata() {
		return tipObjektaDAO.findAll();
	}

	public Mjesto getMjesto() {
		return mjesto;
	}

	public void setMjesto(final Mjesto mjesto) {
		this.mjesto = mjesto;
	}

	// public void clearParameters() {
	// searchParameters.clear();
	// }

	// @Name("osComponents")
	// public static class ObjektSearchComponents {

	public UISelectOne getSelectZupanija() {
		return selectZupanija;
	}

	public void setSelectZupanija(final UISelectOne selectZupanija) {
		this.selectZupanija = selectZupanija;
	}

	public UISelectOne getSelectOtok() {
		return selectOtok;
	}

	public void setSelectOtok(final UISelectOne selectOtok) {
		this.selectOtok = selectOtok;
	}

	public UISelectOne getSelectMjesto() {
		return selectMjesto;
	}

	public void setSelectMjesto(final UISelectOne selectMjesto) {
		this.selectMjesto = selectMjesto;
	}

	public UISelectOne getSelectPosta() {
		return selectPosta;
	}

	public void setSelectPosta(final UISelectOne selectPosta) {
		this.selectPosta = selectPosta;
	}

	public UISelectOne getSelectTipObjekta() {
		return selectTipObjekta;
	}

	public void setSelectTipObjekta(final UISelectOne selectTipObjekta) {
		this.selectTipObjekta = selectTipObjekta;
	}

	@Factory("objekti")
	public DataModel getSearchResults() { // return new
		// SearchResultsDataModel(searchParameters);
		if (page == null) {
			page = 1;
		}
		if (idTipaObjekta != null) {
			searchParameters.setTipObjekta(new TipObjekta(idTipaObjekta));
		}
		if (idMjesta != null) {
			searchParameters.setMjesto(new Mjesto(idMjesta));
			searchParameters.setOtok(null);
			searchParameters.setZupanija(null);
		}
		if (idOtoka != null) {
			searchParameters.setOtok(new Otok(idOtoka));
			searchParameters.setMjesto(null);
			searchParameters.setZupanija(null);
		}
		if (idZupanije != null) {
			searchParameters.setZupanija(new Zupanija(idZupanije));
			searchParameters.setOtok(null);
			searchParameters.setMjesto(null);
		}

		final ObjektDAO objektDAO = (ObjektDAO) Component
				.getInstance("objektDAO");
		int count = objektDAO.findCountByCriteria(searchParameters);
		List<Objekt> objekti = new ArrayList<Objekt>();
		List<Object[]> idObjektaList = objektDAO.findByCriteria(
				searchParameters, page * PAGE_SIZE - PAGE_SIZE, PAGE_SIZE);
		if (idObjektaList.size() > 0) {
			List<Objekt> objRetVal = objektDAO
					.findObjektiByIdObjektaList(idObjektaList);
			for (Object[] proj : idObjektaList) {
				for (Objekt objekt : objRetVal) {
					if (proj[0].equals(objekt.getIdObjekta())) {
						objekt.setOcjena((Double) proj[1]);
						objekt.setBrojDojmova((Integer) proj[2]);
						objekt.setBrojSlika((Integer) proj[3]);
						objekti.add(objekt);
						break;
					}
				}
			}

			return new PagedListDataModel(objekti, count, PAGE_SIZE);
		}
		return null;
	}
}